/*****************************************************************************
 * $LastChangedDate: 2010-03-26 15:04:03 -0400 (Fri, 26 Mar 2010) $
 * @file
 * @author  Jim E. Brooks  http://www.palomino3d.org
 * @brief   Interface to light sources implemented by shaders and hw.
 *//*
 * LEGAL:   COPYRIGHT (C) 2009 JIM E. BROOKS
 *          THIS SOURCE CODE IS RELEASED UNDER THE TERMS
 *          OF THE GNU GENERAL PUBLIC LICENSE VERSION 2 (GPL 2).
 *****************************************************************************/

#define SHADER_LIGHT_CC 1
#include "base/module.hh"
using namespace base;
#include "shader/module.hh"
#include "shader/light.hh"
#include "shader/light_shader.hh"
#if COMPILE_HW_LIGHT
#include "shader/light_hw.hh"
#endif

namespace shader {

////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////  Light  //////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

Light* Light::msInstance;

/*****************************************************************************
 * ctor/dtor.
 *****************************************************************************/
Light::Light( void )
:   mShaderLight(GET_SHADER_LIGHT())
#if COMPILE_HW_LIGHT
    ,mHwLight(GET_HW_LIGHT())
#endif    
{
    // NOP
}

Light::~Light()
{
    // NOP
}

/*****************************************************************************
 * Set type of light (positional, directional).
 *****************************************************************************/
void
Light::SetLightType( const uint lightNum, const shader::defs::eLightType type )
{
    mShaderLight.SetLightType( lightNum, type );
#if COMPILE_HW_LIGHT
    mHwLight.SetLightType( lightNum, type );
#endif
}

/*****************************************************************************
 * Set position of a light source.
 *****************************************************************************/
void
Light::SetLightPosition( const uint lightNum, const WorldVertex& pos )
{
    mShaderLight.SetLightPosition( lightNum, pos );
#if COMPILE_HW_LIGHT
    mHwLight.SetLightPosition( lightNum, pos );
#endif
}

/*****************************************************************************
 * @return Position of a light.
 *****************************************************************************/
WorldVertex
Light::GetLightPosition( const uint lightNum )
{
    return mShaderLight.GetLightPosition( lightNum );
}

/*****************************************************************************
 * Set the color of a light source.
 *****************************************************************************/
void
Light::SetLightColor( const uint lightNum, const RGBA color )
{
    mShaderLight.SetLightColor( lightNum, color );
#if COMPILE_HW_LIGHT
    mHwLight.SetLightColor( lightNum, color );
#endif
}

/*****************************************************************************
 * Set brightness of all lights.
 * @param   brightness
 * @param   setting
 *          BRIGHTNESS_ABSOLUTE sets value directly.
 *          BRIGHTNESS_RELATIVE accounts for -brightness arg.
 *****************************************************************************/
void
Light::SetLightBrightness( const fp brightness, const shader::defs::eBrightness setting )
{
    mShaderLight.SetLightBrightness( brightness, setting );
#if COMPILE_HW_LIGHT
    mHwLight.SetLightBrightness( brightness, setting );
#endif
}

/*****************************************************************************
 * @return Brightness of all lights.
 *****************************************************************************/
fp
Light::GetLightBrightness( void )
{
    return mShaderLight.GetLightBrightness();
}

/*****************************************************************************
 * Set base ambient of all lights.
 *****************************************************************************/
void
Light::SetLightBaseAmbient( const RGBA color )
{
    mShaderLight.SetLightBaseAmbient( color );
#if COMPILE_HW_LIGHT
    mHwLight.SetLightBaseAmbient( color );
#endif
}

/*****************************************************************************
 * Set fog density.
 *****************************************************************************/
void
Light::SetFogDensity( const fpx fogDensity, const osg::Fog::Mode fogMode )
{
    mShaderLight.SetFogDensity( fogDensity, fogMode );
#if COMPILE_HW_LIGHT
    mHwLight.SetFogDensity( fogDensity, fogMode );
#endif
}

/*****************************************************************************
 * Set fog color.
 *****************************************************************************/
void
Light::SetFogColor( const RGBA fogColor )
{
    mShaderLight.SetFogColor( fogColor );
#if COMPILE_HW_LIGHT
    mHwLight.SetFogColor( fogColor );
#endif
}

/*****************************************************************************
 * Set minimum fog (unit range).
 * This ensures that near objects have some fog.
 *****************************************************************************/
void
Light::SetFogMin( const fp fogMin )
{
    mShaderLight.SetFogMin( fogMin );
#if COMPILE_HW_LIGHT
    mHwLight.SetFogMin( fogMin );
#endif
}

} // namespace shader
